package com.element.oauth2.server.global.generator;

import com.common.core.utils.MDFiveUtil;
import com.element.oauth2.constant.SecurityParams;
import org.springframework.lang.Nullable;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;

import java.time.Instant;

public class OAuthRefreshTokenGenerator implements OAuth2TokenGenerator<OAuth2RefreshToken> {

    private final OAuth2AuthorizationService oAuth2AuthorizationService;

    public OAuthRefreshTokenGenerator(OAuth2AuthorizationService oAuth2AuthorizationService) {
        this.oAuth2AuthorizationService = oAuth2AuthorizationService;
    }

    @Nullable
    @Override
    public OAuth2RefreshToken generate(OAuth2TokenContext context) {
        if (!OAuth2TokenType.REFRESH_TOKEN.equals(context.getTokenType())) {
            return null;
        } else {
            OAuth2Authorization authorization = context.getAuthorization();
            // 刷新token逻辑,删除已存在的
            if (null != authorization) {
                oAuth2AuthorizationService.remove(authorization);
            }
            String refreshToken = "R" + MDFiveUtil.getOnlyId();
            // 获取当前人有无授权信息
            RegisteredClient registeredClient = context.getRegisteredClient();
            AuthorizationGrantType grantType = context.get(AuthorizationGrantType.class);
            if (null != registeredClient && null != grantType) {
                String key = SecurityParams.SPRING_SECURITY_USER_TOKEN_KEY(registeredClient.getClientId(), grantType.getValue(), context.getPrincipal().getName());
                OAuth2Authorization oAuth2Authorization = oAuth2AuthorizationService.findById(key);
                if (null != oAuth2Authorization) {
                    OAuth2Authorization.Token<OAuth2RefreshToken> token = oAuth2Authorization.getRefreshToken();
                    if (null != token && null != token.getToken()) {
                        refreshToken = token.getToken().getTokenValue();
                    }
                }
            }
            Instant issuedAt = Instant.now();
            Instant expiresAt = issuedAt.plus(context.getRegisteredClient().getTokenSettings().getRefreshTokenTimeToLive());
            return new OAuth2RefreshToken(refreshToken, issuedAt, expiresAt);
        }
    }
}
